/** @file    CoderXML_Building.cpp
 *  @author  Alessandro Polo
 *  @version $Id: CoderXML_Building.cpp 2080 2010-03-10 05:38:54Z alex $
 *  @brief
 * File containing methods for Serialization.
 ****************************************************************************/
/* Copyright (c) 2007-2010, WOSH - Wide Open Smart Home 
 * by Alessandro Polo - OpenSmartHome.com
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or materials provided with the distribution.
 *     * Neither the name of the OpenSmartHome.com WOSH nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY Alessandro Polo ''AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL Alessandro Polo BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ****************************************************************************/

 #include <framework/database/CoderXML_Building.h>
 #include <framework/database/CoderXML_Core.h>
 #include <framework/database/EncoderXML.h>


using namespace std;
using namespace wosh::building;
namespace wosh {
 namespace database {

void EncoderXML_register_Buildings()
 {
	EncoderXML::registerDataType( _BuildingGeometry_TYPE,	new EncoderXML_template__BuildingGeometry() );

	EncoderXML::registerDataType( _Appliance_TYPE,	new EncoderXML_template__Appliance() );
	EncoderXML::registerDataType( _AudioBox_TYPE,	new EncoderXML_template__AudioBox() );
	EncoderXML::registerDataType( _Door_TYPE,		new EncoderXML_template__Door() );
	EncoderXML::registerDataType( _DoorBell_TYPE,	new EncoderXML_template__DoorBell() );
	EncoderXML::registerDataType( _Floor_TYPE,		new EncoderXML_template__Floor() );
	EncoderXML::registerDataType( _House_TYPE,		new EncoderXML_template__House() );
	EncoderXML::registerDataType( _Garden_TYPE,		new EncoderXML_template__Garden() );
	EncoderXML::registerDataType( _Light_TYPE,		new EncoderXML_template__Light() );
	EncoderXML::registerDataType( _Room_TYPE,		new EncoderXML_template__Room() );
	EncoderXML::registerDataType( _Window_TYPE,		new EncoderXML_template__Window() );
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

WRESULT EncoderXML_template__BuildingObject::serializeTo( const ISerializable* object_s, QDomDocument& doc, QDomElement& contNode, bool compact )
 {
	if ( object_s == NULL ) return WRET_ERR_PARAM;
	const wosh::building::BuildingObject* object = dynamic_cast<const wosh::building::BuildingObject*>(object_s);
	if ( object == NULL ) return WRET_ERR_PARAM;
	WRESULT ret = WRET_OK;

	if ( compact ) {
		ret += EncoderXML_template__Object().serializeTo( object, doc, contNode, true );

	 }
	else {
		QDomElement objectNode = doc.createElement("object");
		contNode.appendChild(objectNode);
		ret += EncoderXML_template__Object().serializeTo( object, doc, objectNode, false );

	 }

	if ( object->countChildren() != 0 ) {
		QDomElement childrenNode = doc.createElement("children");
		contNode.appendChild(childrenNode);

		std::vector<std::string> keys;
		object->getChildren(keys);
		std::vector<std::string>::const_iterator it;

		for ( it=keys.begin(); it!=keys.end(); ++it ) {
			QDomElement childNode = doc.createElement("wosh::Object");
			childNode.setAttribute("uri", QString((*it).c_str()) );
			childrenNode.appendChild(childNode);
		 }
	}

	QDomElement node_geometry = doc.createElement("geometry");
	ret += EncoderXML_template__BuildingGeometry().serializeTo( &object->getGeometry(), doc, node_geometry, true );
	contNode.appendChild(node_geometry);

	QDomElement node_properties = doc.createElement("properties");
	ret += EncoderXML_template__PropertiesProvider().serializeTo( &object->getProperties(), doc, node_properties, true );
	contNode.appendChild(node_properties);

	return ret;
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

WRESULT EncoderXML_template__BuildingObject::deserializeFrom( ISerializable* object_s, const QDomElement& contNode )
 {
 	if ( object_s == NULL ) return WRET_ERR_PARAM;
	wosh::building::BuildingObject* object = dynamic_cast<wosh::building::BuildingObject*>(object_s);
	if ( object == NULL ) return WRET_ERR_PARAM;
	WRESULT ret = WRET_OK;

	string typeOverride = object->getClassName();
	QDomElement objectNode = contNode.namedItem("object").toElement();
	if ( !objectNode.isNull() )
		ret += EncoderXML_template__Object().deserializeFrom( object, objectNode );
	else
		ret += EncoderXML_template__Object().deserializeFrom( object, contNode );

	// bugfix of Serialization loading (it doesnt call the upper implementation due to (virtual) casting)
	object->setType(typeOverride);
	object->setPermission(object->getPermission());

	std::string tagname;
	std::string objUri;
	std::string interfaces;
	QDomElement childrenNode = contNode.namedItem("children").toElement();
	if ( !childrenNode.isNull() ) {
		QDomNodeList nodesList = childrenNode.childNodes();
		for( unsigned int j=0; j<nodesList.length(); ++j ) {
			QDomElement childNode = nodesList.item(j).toElement();
			tagname = string( childNode.tagName().toLatin1().data() );
			objUri= string( childNode.attribute("uri").toLatin1().data() );
			if ( objUri.size() < 3 ) {
				continue;
			 }
			interfaces = string( childNode.attribute("interfaces").toLatin1().data() );
			InterfacesProvider* ip = new InterfacesProvider();
			ip->fromString(interfaces);
			if ( interfaces.empty() )
				ip->add(tagname);
			object->setChild( objUri, ip );
		 }
	 }

	QDomElement geomNode = contNode.namedItem("geometry").toElement();
	if ( !geomNode.isNull() ) {
		ret += EncoderXML_template__BuildingGeometry().deserializeFrom( &object->getGeometry(), geomNode );
	 }

	QDomElement propsNode = contNode.namedItem("properties").toElement();
	if ( !propsNode.isNull() ) {
		ret += EncoderXML_template__PropertiesProvider().deserializeFrom( &object->getProperties(), propsNode );
	 }

	return ret;
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

WRESULT EncoderXML_template__BuildingGeometry::serializeTo( const ISerializable* object_s, QDomDocument& doc, QDomElement& contNode, bool compact )
 {
	if ( object_s == NULL ) return WRET_ERR_PARAM;
	const wosh::building::BuildingGeometry* object = dynamic_cast<const wosh::building::BuildingGeometry*>(object_s);
	if ( object == NULL ) return WRET_ERR_PARAM;
	WRESULT ret = WRET_OK;
	(void)compact;

	QDomElement posNode = doc.createElement("position");
	posNode.setAttribute("x", object->getPosition().x );
	posNode.setAttribute("y", object->getPosition().y );
	posNode.setAttribute("z", object->getPosition().z );
	contNode.appendChild(posNode);

	return ret;
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

WRESULT EncoderXML_template__BuildingGeometry::deserializeFrom( ISerializable* object_s, const QDomElement& contNode )
 {
 	if ( object_s == NULL ) return WRET_ERR_PARAM;
	wosh::building::BuildingGeometry* object = dynamic_cast<wosh::building::BuildingGeometry*>(object_s);
	if ( object == NULL ) return WRET_ERR_PARAM;
	WRESULT ret = WRET_OK;

	QDomElement posNode = contNode.namedItem("position").toElement();
	if ( !posNode.isNull() ) {
		Point3D pos = object->getPosition();

		QDomElement xNode = posNode.namedItem("x").toElement();
		if ( !xNode.isNull() ) pos.x = xNode.text().toFloat();
		else if ( posNode.hasAttribute("x") ) pos.x = posNode.attribute("x").toFloat();

		QDomElement yNode = posNode.namedItem("y").toElement();
		if ( !yNode.isNull() ) pos.y = yNode.text().toFloat();
		else if ( posNode.hasAttribute("y") ) pos.y = posNode.attribute("y").toFloat();

		QDomElement zNode = posNode.namedItem("z").toElement();
		if ( !zNode.isNull() ) pos.z = zNode.text().toFloat();
		else if ( posNode.hasAttribute("z") ) pos.z = posNode.attribute("z").toFloat();

		object->setPosition(pos);
	 }

	return ret;
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

WRESULT EncoderXML_template__Appliance::serializeTo( const ISerializable* object_s, QDomDocument& doc, QDomElement& contNode, bool compact )
 {
	if ( object_s == NULL ) return WRET_ERR_PARAM;
	const wosh::building::Appliance* object = dynamic_cast<const wosh::building::Appliance*>(object_s);
	if ( object == NULL ) return WRET_ERR_PARAM;
	WRESULT ret = WRET_OK;

	ret = EncoderXML_template__BuildingObject().serializeTo( object_s, doc, contNode, compact );

	return ret;
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

WRESULT EncoderXML_template__Appliance::deserializeFrom( ISerializable* object_s, const QDomElement& contNode )
 {
 	if ( object_s == NULL ) return WRET_ERR_PARAM;
	wosh::building::Appliance* object = dynamic_cast<wosh::building::Appliance*>(object_s);
	if ( object == NULL ) return WRET_ERR_PARAM;
	WRESULT ret = WRET_OK;

	ret = EncoderXML_template__BuildingObject().deserializeFrom( object_s, contNode );

	return ret;
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

WRESULT EncoderXML_template__AudioBox::serializeTo( const ISerializable* object_s, QDomDocument& doc, QDomElement& contNode, bool compact )
 {
	if ( object_s == NULL ) return WRET_ERR_PARAM;
	const wosh::building::AudioBox* object = dynamic_cast<const wosh::building::AudioBox*>(object_s);
	if ( object == NULL ) return WRET_ERR_PARAM;
	WRESULT ret = WRET_OK;

	ret = EncoderXML_template__BuildingObject().serializeTo( object_s, doc, contNode, compact );

	return ret;
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

WRESULT EncoderXML_template__AudioBox::deserializeFrom( ISerializable* object_s, const QDomElement& contNode )
 {
 	if ( object_s == NULL ) return WRET_ERR_PARAM;
	wosh::building::AudioBox* object = dynamic_cast<wosh::building::AudioBox*>(object_s);
	if ( object == NULL ) return WRET_ERR_PARAM;
	WRESULT ret = WRET_OK;

	ret = EncoderXML_template__BuildingObject().deserializeFrom( object_s, contNode );

	return ret;
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

WRESULT EncoderXML_template__Door::serializeTo( const ISerializable* object_s, QDomDocument& doc, QDomElement& contNode, bool compact )
 {
	if ( object_s == NULL ) return WRET_ERR_PARAM;
	const wosh::building::Door* object = dynamic_cast<const wosh::building::Door*>(object_s);
	if ( object == NULL ) return WRET_ERR_PARAM;
	WRESULT ret = WRET_OK;

	ret = EncoderXML_template__BuildingObject().serializeTo( object_s, doc, contNode, compact );

	return ret;
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

WRESULT EncoderXML_template__Door::deserializeFrom( ISerializable* object_s, const QDomElement& contNode )
 {
 	if ( object_s == NULL ) return WRET_ERR_PARAM;
	wosh::building::Door* object = dynamic_cast<wosh::building::Door*>(object_s);
	if ( object == NULL ) return WRET_ERR_PARAM;
	WRESULT ret = WRET_OK;

	ret = EncoderXML_template__BuildingObject().deserializeFrom( object_s, contNode );

	return ret;
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

WRESULT EncoderXML_template__DoorBell::serializeTo( const ISerializable* object_s, QDomDocument& doc, QDomElement& contNode, bool compact )
 {
	if ( object_s == NULL ) return WRET_ERR_PARAM;
	const wosh::building::DoorBell* object = dynamic_cast<const wosh::building::DoorBell*>(object_s);
	if ( object == NULL ) return WRET_ERR_PARAM;
	WRESULT ret = WRET_OK;

	ret = EncoderXML_template__BuildingObject().serializeTo( object_s, doc, contNode, compact );

	return ret;
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

WRESULT EncoderXML_template__DoorBell::deserializeFrom( ISerializable* object_s, const QDomElement& contNode )
 {
 	if ( object_s == NULL ) return WRET_ERR_PARAM;
	wosh::building::DoorBell* object = dynamic_cast<wosh::building::DoorBell*>(object_s);
	if ( object == NULL ) return WRET_ERR_PARAM;
	WRESULT ret = WRET_OK;

	ret = EncoderXML_template__BuildingObject().deserializeFrom( object_s, contNode );

	return ret;
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

WRESULT EncoderXML_template__Floor::serializeTo( const ISerializable* object_s, QDomDocument& doc, QDomElement& contNode, bool compact )
 {
	if ( object_s == NULL ) return WRET_ERR_PARAM;
	const wosh::building::Floor* object = dynamic_cast<const wosh::building::Floor*>(object_s);
	if ( object == NULL ) return WRET_ERR_PARAM;
	WRESULT ret = WRET_OK;

	ret = EncoderXML_template__BuildingObject().serializeTo( object_s, doc, contNode, compact );

	return ret;
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

WRESULT EncoderXML_template__Floor::deserializeFrom( ISerializable* object_s, const QDomElement& contNode )
 {
 	if ( object_s == NULL ) return WRET_ERR_PARAM;
	wosh::building::Floor* object = dynamic_cast<wosh::building::Floor*>(object_s);
	if ( object == NULL ) return WRET_ERR_PARAM;
	WRESULT ret = WRET_OK;

	ret = EncoderXML_template__BuildingObject().deserializeFrom( object_s, contNode );

	return ret;
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

WRESULT EncoderXML_template__Garden::serializeTo( const ISerializable* object_s, QDomDocument& doc, QDomElement& contNode, bool compact )
 {
	if ( object_s == NULL ) return WRET_ERR_PARAM;
	const wosh::building::Garden* object = dynamic_cast<const wosh::building::Garden*>(object_s);
	if ( object == NULL ) return WRET_ERR_PARAM;
	WRESULT ret = WRET_OK;

	ret = EncoderXML_template__Floor().serializeTo( object_s, doc, contNode, compact );

	return ret;
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

WRESULT EncoderXML_template__Garden::deserializeFrom( ISerializable* object_s, const QDomElement& contNode )
 {
 	if ( object_s == NULL ) return WRET_ERR_PARAM;
	wosh::building::Garden* object = dynamic_cast<wosh::building::Garden*>(object_s);
	if ( object == NULL ) return WRET_ERR_PARAM;
	WRESULT ret = WRET_OK;

	ret = EncoderXML_template__Floor().deserializeFrom( object_s, contNode );

	return ret;
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

WRESULT EncoderXML_template__House::serializeTo( const ISerializable* object_s, QDomDocument& doc, QDomElement& contNode, bool compact )
 {
	if ( object_s == NULL ) return WRET_ERR_PARAM;
	const wosh::building::House* object = dynamic_cast<const wosh::building::House*>(object_s);
	if ( object == NULL ) return WRET_ERR_PARAM;
	WRESULT ret = WRET_OK;

	ret = EncoderXML_template__BuildingObject().serializeTo( object_s, doc, contNode, compact );

	return ret;
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

WRESULT EncoderXML_template__House::deserializeFrom( ISerializable* object_s, const QDomElement& contNode )
 {
 	if ( object_s == NULL ) return WRET_ERR_PARAM;
	wosh::building::House* object = dynamic_cast<wosh::building::House*>(object_s);
	if ( object == NULL ) return WRET_ERR_PARAM;
	WRESULT ret = WRET_OK;

	ret = EncoderXML_template__BuildingObject().deserializeFrom( object_s, contNode );

	return ret;
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

WRESULT EncoderXML_template__Light::serializeTo( const ISerializable* object_s, QDomDocument& doc, QDomElement& contNode, bool compact )
 {
	return EncoderXML_template__Appliance::serializeTo( object_s, doc, contNode, compact );
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

WRESULT EncoderXML_template__Light::deserializeFrom( ISerializable* object_s, const QDomElement& contNode )
 {
	return EncoderXML_template__Appliance::deserializeFrom( object_s, contNode );
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

WRESULT EncoderXML_template__Room::serializeTo( const ISerializable* object_s, QDomDocument& doc, QDomElement& contNode, bool compact )
 {
	if ( object_s == NULL ) return WRET_ERR_PARAM;
	const wosh::building::Room* object = dynamic_cast<const wosh::building::Room*>(object_s);
	if ( object == NULL ) return WRET_ERR_PARAM;
	WRESULT ret = WRET_OK;

	ret = EncoderXML_template__BuildingObject().serializeTo( object_s, doc, contNode, compact );

	return ret;
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

WRESULT EncoderXML_template__Room::deserializeFrom( ISerializable* object_s, const QDomElement& contNode )
 {
 	if ( object_s == NULL ) return WRET_ERR_PARAM;
	wosh::building::Room* object = dynamic_cast<wosh::building::Room*>(object_s);
	if ( object == NULL ) return WRET_ERR_PARAM;
	WRESULT ret = WRET_OK;

	ret = EncoderXML_template__BuildingObject().deserializeFrom( object_s, contNode );

	return ret;
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

WRESULT EncoderXML_template__Window::serializeTo( const ISerializable* object_s, QDomDocument& doc, QDomElement& contNode, bool compact )
 {
	if ( object_s == NULL ) return WRET_ERR_PARAM;
	const wosh::building::Window* object = dynamic_cast<const wosh::building::Window*>(object_s);
	if ( object == NULL ) return WRET_ERR_PARAM;
	WRESULT ret = WRET_OK;

	ret = EncoderXML_template__BuildingObject().serializeTo( object_s, doc, contNode, compact );

	return ret;
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

WRESULT EncoderXML_template__Window::deserializeFrom( ISerializable* object_s, const QDomElement& contNode )
 {
 	if ( object_s == NULL ) return WRET_ERR_PARAM;
	wosh::building::Window* object = dynamic_cast<wosh::building::Window*>(object_s);
	if ( object == NULL ) return WRET_ERR_PARAM;
	WRESULT ret = WRET_OK;

	ret = EncoderXML_template__BuildingObject().deserializeFrom( object_s, contNode );

	return ret;
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

 }; // namespace database
}; // namespace wosh
